//
//
//

#include <zneo.h>

#include "timer.h"
#include "led.h"
#include "ledmatrix.h"

void DrawLoop(void);
void Pause(void);
void DisplayPhrase(char _c);


void main() {
	char c;

	DI();

	InitSystemClock();
	InitLEDs();
	InitLEDMatrixes();
	InitTimer();

	ClearLEDMatrix(0);
	EI();

	ResetTime();
	//StartTimer();

	while (1) {
		DrawLoop();
	}
}


#define STOPPED  0x00
#define RUNNING  0x01
#define PAUSED   0x02

#define DEBOUNCE 0x07
#define DEBOUNCE_DN(x) ((x & DEBOUNCE) == DEBOUNCE)
#define DEBOUNCE_UP(x) ((x | ~DEBOUNCE) == ~DEBOUNCE)


short state = STOPPED;

unsigned int timeToDisplay;

unsigned short volatile b1up   =0;
unsigned short volatile b1state=0;
unsigned short volatile b2up   =0;
unsigned short volatile b2state=0;
unsigned short volatile b3up   =0;
unsigned short volatile b3state=0;

void CheckButtons(void) {
	b1state <<= 1;
	b2state <<= 1;
	b3state <<= 1;

	if ((PDIN & 0x08) != 0x08){
		b1state |= 0x01;
	}

	if ((PFIN & 0x40) != 0x40){
		b2state |= 0x01;
	}

	if ((PFIN & 0x80) != 0x80){
		b3state |= 0x01;
	}
}


void ManageState(void) {

	if (DEBOUNCE_UP(b1state)) {
		b1up = 1;
	}

	if (DEBOUNCE_UP(b2state)) {
		b2up = 1;
	}

	if ((state & RUNNING) == RUNNING) {
		if (b1up > 0 && DEBOUNCE_DN(b1state)) {
			b1up = 0;
			state &= ~RUNNING;
			StopTimer();
		}
	} else {
		if (b1up > 0 && DEBOUNCE_DN(b1state)) {
			b1up = 0;
			state |= RUNNING;
			StartTimer();
		}
	}

	if ((state & PAUSED) == PAUSED){
		if (b2up > 0 && DEBOUNCE_DN(b2state)) {
			b2up = 0;
			state &= ~PAUSED;
		}
	} else {
		if (b2up > 0 && DEBOUNCE_DN(b2state)) {
			b2up = 0;
			state |= PAUSED;
			timeToDisplay = GetTime();
		}
	}

	if (DEBOUNCE_DN(b3state)) {
		ResetTime();
		timeToDisplay = 0;
		if ((state & RUNNING) == RUNNING) {
			StopTimer();
		}
		state = STOPPED;
	}

	SetLEDs(state);
}

void DrawState(void) {
	unsigned int time = ((state & PAUSED) == PAUSED) ? timeToDisplay : GetTime();
	//unsigned int time = (1==1) ? timeToDisplay : GetTime();
	//unsigned int time = GetTime();

	char tenths = '0' + ( time       % 10);
	char ones   = '0' + ((time/10)   % 10);
	char tens   = '0' + ((time/100)  % 10);
	char hundrs = '0' + ((time/1000) % 10);

	SetLEDMatrix(1, hundrs);
	SetLEDMatrix(2, tens);
	SetLEDMatrix(3, ones);
	SetLEDMatrix(4, tenths);
}

void DrawLoop(void) {
	CheckButtons();
	ManageState();
	DrawState();
}

void DisplayPhrase(char _c) {
	short i,j;
	short x;
	short p;

	p=-1;

	for(i=0; i<0x7F; ++i){

		if(p<0 && (PDIN & 0x08) != 0x08)
			p=i;
		else if(p>=0 && (PDIN & 0x08) == 0x08)
			p=-1;

		if(p>=0)
			i=p;

		for(j=0; j<0x07; ++j){


			if((PDIN & 0x08) != 0x08)
				--j;

			for(x=0;x<4;++x){

				SetLEDMatrix(x+1, 'A'+((_c+x-'A')%26));

			}
		}
	}
}

// button1 -> PD3
// button2 -> PF6
// button3 -> PF7